package com.example.spring.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.example.spring.demo.config.properties.MyDataSourceProperty;
import com.example.spring.demo.config.properties.MyShardingConfigProperties;
import com.example.spring.demo.config.properties.MyShardingRuleProperty;
import com.example.spring.demo.config.strategy.MyShardingDataSourceAlgorithm;
import com.example.spring.demo.config.strategy.MyShardingTableAlgorithm;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.StandardShardingStrategyConfiguration;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

/**
 * @author liangchao
 * 11/18/18 8:57 PM
 */
@Configuration
@EnableConfigurationProperties({MyShardingConfigProperties.class})
public class MyShardingConfig {

    @Bean //自动注入properties
    public DataSource getShardingDataSource(MyShardingConfigProperties properties) throws SQLException {
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        //设置所有的数据源 dataSource
        for (int i = 0; i < properties.getDatasource().size(); i++) {
            MyDataSourceProperty property = properties.getDatasource().get(i);
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setDriverClassName(property.getDriverClass());
            druidDataSource.setUrl(property.getUrl());
            druidDataSource.setUsername(property.getUsername());
            druidDataSource.setPassword(property.getPassword());
            dataSourceMap.put(MyShardingUtil.getDataSourceKey(i), druidDataSource);
        }

        for (int i = 0; i < properties.getRule().size(); i++) {
            MyShardingRuleProperty ruleProperty = properties.getRule().get(i);
            // 设置所有的分库分表规则
            TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration();
            orderTableRuleConfig.setLogicTable(ruleProperty.getTableName());
            List<String> dataNodes = new ArrayList<>();
            List<String> tableNames = MyShardingUtil.getTableNames(ruleProperty);
            for (String dataSourceKey : dataSourceMap.keySet()) {
                for (String tableName : tableNames) {
                    dataNodes.add(dataSourceKey + "." + tableName);
                }
            }
            orderTableRuleConfig.setActualDataNodes(String.join(",", dataNodes));
            orderTableRuleConfig.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration(ruleProperty.getColumnName(), MyShardingDataSourceAlgorithm.class.getName()));
            orderTableRuleConfig.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration(ruleProperty.getColumnName(), MyShardingTableAlgorithm.class.getName()));
            shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);
        }

        // config order_item table rule...
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new HashMap<>(), new Properties());
        return dataSource;
    }


}
